Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

added workflow start-update-with-start and workflow execute-update-with-start commands #762

Merged
merged 4 commits into from
Feb 28, 2025

Conversation

THardy98
Copy link
Contributor

@THardy98 THardy98 commented Feb 25, 2025

added temporal workflow start-update-with-start and temporal workflow execute-update-with-start commands

temporal workflow start-update-with-start usage:

    temporal workflow start-update-with-start \
      --update-name YourUpdate \
      --update-input '{"update-key": "update-value"}' \
      --update-wait-for-stage accepted \
      --workflow-id YourWorkflowId \
      --type YourWorkflowType \
      --task-queue YourTaskQueue \
      --id-conflict-policy Fail \
      --input '{"wf-key": "wf-value"}'

temporal workflow execute-update-with-start usage:

  temporal workflow execute-update-with-start \
    --update-name YourUpdate \
    --update-input '{"update-key": "update-value"}' \
    --workflow-id YourWorkflowId \
    --type YourWorkflowType \
    --task-queue YourTaskQueue \
    --id-conflict-policy Fail \
    --input '{"wf-key": "wf-value"}'
  1. Closes UpdateWithStart SDK API #664

  2. How was this tested:

  1. Any docs updates needed?
    Yes

@THardy98 THardy98 requested review from cretz and dandavison February 25, 2025 06:49
@THardy98
Copy link
Contributor Author

Need to add tests, but feel free to take a look at the command interface and behaviour

Comment on lines +301 to +305
var valuePtr interface{}
err = handle.Get(cctx, &valuePtr)
if err != nil {
return fmt.Errorf("unable to update workflow: %w", err)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a bit of a problem with this approach and the one taken by temporal workflow update execute. This presumes that the result can be JSON decoded, but many people use protos or other formats. On user-defined results we need to support all payloads (gracefully using JSON where we can). I believe this is the first time we have needed to get a raw payload from a high-level client call to display to a user.

I think we need to add support for rawValuePayloadConverter.FromPayload in client.go, then change the code in this PR to be something like:

var raw RawValue
if err = handle.Get(cctx, raw); err != nil {
	return fmt.Errorf("unable to update workflow: %w", err)
}
result, err := cctx.MarshalFriendlyJSONPayloads(raw.Payload)

And have Result in the structure be a json.RawMessage. Same for temporal workflow update. And confirm it looks right even with -o json. Thoughts @THardy98 and @dandavison?

…rom printed output of commands because we cannot guarantee the task queue used is the one the user supplied
@THardy98
Copy link
Contributor Author

THardy98 commented Feb 28, 2025

I removed TaskQueue from stdout ouput for the -with-start commands because we cannot guarantee the supplied TaskQueue is the one the signal/update ran on (i.e. in the scenario that an existing workflow with the same ID ran on a different task queue).

Also refactored the SignalWithStart tests a bit as well.

@THardy98 THardy98 requested review from dandavison and cretz February 28, 2025 02:51
Comment on lines +248 to +260
// Currently we only accept 'accepted' as a valid wait for stage value, but we intend
// to support more in the future.
if waitForStage == client.WorkflowUpdateStageAccepted {
// Use a canceled context to check whether the initial server response
// shows that the update has _already_ failed, without issuing a second request.
ctx, cancel := context.WithCancel(cctx)
cancel()
err = handle.Get(ctx, nil)
var timeoutOrCanceledErr *client.WorkflowUpdateServiceTimeoutOrCanceledError
if err != nil && !errors.As(err, &timeoutOrCanceledErr) {
return fmt.Errorf("unable to update workflow: %w", err)
}
}
Copy link
Member

@cretz cretz Feb 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrmm, I don't think UpdateWithStartWorkflow will return until it is at least accepted or rejected, and if there is some error, it will be reflected in the error to that call. @dandavison - is this correct?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An example is sending a request for an update name that does not exist. err is nil, but the update is not accepted, and handle contains within it an error, hence this code (which is also present in CLI update impl) to extract that error without making a network request.

Copy link
Member

@cretz cretz Feb 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see, there is "accepted but failed". We should consider adding a Done() bool to WorkflowUpdateHandle for this, but in the meantime, all good here.

(EDIT: Found we do have an issue at temporalio/features#428)

@THardy98 THardy98 merged commit 94883d3 into main Feb 28, 2025
8 checks passed
@THardy98 THardy98 deleted the update-with-start branch February 28, 2025 17:32
@THardy98
Copy link
Contributor Author

TYFR :)

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

UpdateWithStart SDK API
3 participants